package com.net.xpay.common.service.impl;

import com.net.xpay.common.domain.User;
import com.net.xpay.common.domain.partner.PartnerInsiderSettleLog;
import com.net.xpay.common.domain.stat.UserSafePayTransMonthStat;
import com.net.xpay.common.domain.stat.UserTransMonthStat;
import com.net.xpay.common.enums.config.CommonSysConfigKey;
import com.net.xpay.common.enums.user.CommissionMode;
import com.net.xpay.common.helper.CommonSysConfigHelper;
import com.net.xpay.common.manager.UserManager;
import com.net.xpay.common.manager.stat.UserSafePayTransMonthStatManager;
import com.net.xpay.common.manager.stat.UserTransMonthStatManager;
import com.net.common.util.LocalDateUtil;
import com.net.xpay.common.manager.partner.PartnerInsiderSettleLogManager;
import com.net.xpay.common.service.PartnerInsiderSettleLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class PartnerInsiderSettleLogServiceImpl implements PartnerInsiderSettleLogService {


    @Autowired
    private PartnerInsiderSettleLogManager partnerInsiderSettleLogManager;

    @Autowired
    private UserManager userManager;

    @Autowired
    private UserTransMonthStatManager userTransMonthStatManager;

    @Autowired
    private UserSafePayTransMonthStatManager userSafePayTransMonthStatManager;

    @Autowired
    private CommonSysConfigHelper commonSysConfigHelper;


    @Override
    public void doPartnerInsiderSettleLog(int year, int month) {
        List<User> userList = userManager.listByCommissionMode(CommissionMode.STAT_MODE);
        for (User user : userList) {
            if (user.getPartnerId() == null) {
                continue;
            }
            if (user.getRegisterTime().isAfter(LocalDateUtil.getMonthEndDay(LocalDateTime.of(year, month, 1, 0, 0, 0)))) {
                continue;
            }

            PartnerInsiderSettleLog settleLog = new PartnerInsiderSettleLog();
            // 初始化 先去判断该用户当天统计记录是否存在
            settleLog.setPartnerId(user.getPartnerId());
            settleLog.setUserId(user.getId());
            settleLog.setYear(year);
            settleLog.setMonth(month);
            boolean exitRecord = hasStated(settleLog);
            if (exitRecord) {
                log.warn("doPartnerInsiderSettleLog the record of partnerId={} is already exist", user.getPartnerId());
                return;
            }

            //统计数据并入库
            savePartnerInsiderSettleLog(year, month, settleLog, user);
        }
    }

    private void savePartnerInsiderSettleLog(Integer year, Integer month, PartnerInsiderSettleLog settleLog, User user) {
        //统计
        UserTransMonthStat userTransMonthStat = userTransMonthStatManager.findByMonthOfYear(year, month, user.getId());
        UserSafePayTransMonthStat userSafePayTransMonthStat = userSafePayTransMonthStatManager.findByMonthOfYear(year, month, user.getId());
        //设值
        //user
        settleLog.setServiceRatio(user.getServiceRatio());
        settleLog.setBankServiceRatio(user.getBankServiceRatio());
        settleLog.setBenefitRatio(user.getBenefitRatio());
        //userTransMonthStat 批量有密
        settleLog.setTotalPayTransAmount(new BigDecimal(userTransMonthStat.getTotalTransAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setTotalPayTransCount(userTransMonthStat.getTotalCount());
        settleLog.setSuccessPayTransAmount(new BigDecimal(userTransMonthStat.getSuccessAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSuccessPayTransCount(userTransMonthStat.getSuccessCount());
        settleLog.setFailedPayTransAmount(new BigDecimal(userTransMonthStat.getFailedAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setFailPayTransCount(userTransMonthStat.getFailCount());
        settleLog.setTotalPayTransPartnerBenefit(userTransMonthStat.getTotalPartnerBenefit());
        settleLog.setTotalPayTransFatherPartnerBenefit(userTransMonthStat.getTotalFatherPartnerBenefit());
        settleLog.setTotalPayTransPlatformBenefit(userTransMonthStat.getTotalPlatformBenefit());
        settleLog.setPayTransNotFreeSuccessAmount(new BigDecimal(userTransMonthStat.getNotFreeSuccessAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setPayTransNotFreeSuccessCount(userTransMonthStat.getNotFreeSuccessCount());
        settleLog.setPayTransFinalServicePrice(userTransMonthStat.getFinalServicePrice());
        //userSafePayTransMonthStat
        settleLog.setTotalSafePayTransAmount(new BigDecimal(userSafePayTransMonthStat.getTotalTransAmount()));
        settleLog.setTotalSafePayCount(userSafePayTransMonthStat.getTotalCount());
        settleLog.setSuccessSafePayAmount(new BigDecimal(userSafePayTransMonthStat.getSuccessAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSuccessSafePayCount(new BigDecimal(userSafePayTransMonthStat.getSuccessCount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setFailedSafePayAmount(new BigDecimal(userSafePayTransMonthStat.getFailedAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setFailSafePayCount(userSafePayTransMonthStat.getFailCount());
        settleLog.setSuccessSafePayBankAmount(new BigDecimal(userSafePayTransMonthStat.getSuccessBankAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSuccessSafePayBankCount(userSafePayTransMonthStat.getSuccessBankCount());
        settleLog.setSuccessSafePayAlipayAmount(new BigDecimal(userSafePayTransMonthStat.getSuccessAlipayAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSuccessSafePayAlipayCount(userSafePayTransMonthStat.getSuccessAlipayCount());
        settleLog.setSafePayNotFreeSuccessAmount(new BigDecimal(userSafePayTransMonthStat.getNotFreeSuccessAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSafePayNotFreeSuccessCount(userSafePayTransMonthStat.getNotFreeSuccessCount());
        settleLog.setSafePayNotFreeSuccessBankAmount(new BigDecimal(userSafePayTransMonthStat.getNotFreeSuccessBankAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSafePayNotFreeSuccessBankCount(userSafePayTransMonthStat.getNotFreeSuccessBankCount());
        settleLog.setSafePayNotFreeSuccessAlipayAmount(new BigDecimal(userSafePayTransMonthStat.getNotFreeSuccessAlipayAmount()).setScale(2, RoundingMode.HALF_UP));
        settleLog.setSafePayNotFreeSuccessAlipayCount(userSafePayTransMonthStat.getNotFreeSuccessAlipayCount());
        settleLog.setTotalSafePayPartnerBenefit(userSafePayTransMonthStat.getTotalPartnerBenefit());
        settleLog.setTotalSafePayFatherPartnerBenefit(userSafePayTransMonthStat.getTotalFatherPartnerBenefit());
        settleLog.setTotalSafePayPlatformBenefit(userSafePayTransMonthStat.getTotalPlatformBenefit());
        settleLog.setSafePayFinalServicePrice(userSafePayTransMonthStat.getFinalServicePrice());
        //总值
        settleLog.setTotalFinalServicePrice(settleLog.getPayTransFinalServicePrice() + settleLog.getSafePayFinalServicePrice());
        //充值成本
        BigDecimal chargeCost = new BigDecimal(settleLog.getTotalFinalServicePrice()).multiply(new BigDecimal("0.01")).multiply(new BigDecimal("0.006"));
        //到卡成本
        BigDecimal bankRatio = new BigDecimal(commonSysConfigHelper.getString(CommonSysConfigKey.SINGE_TRANS_BANK_COST_RATIO));
        BigDecimal bankCost = settleLog.getSuccessSafePayBankAmount().multiply(bankRatio);

        //最终受益
        BigDecimal partnerSettleAmount = new BigDecimal(settleLog.getTotalFinalServicePrice()).multiply(new BigDecimal("0.01")).subtract(chargeCost).subtract(bankCost).multiply(settleLog.getBenefitRatio()).setScale(2, RoundingMode.HALF_UP);

        log.info("partnerId={}|partnerSettleAmount={}|bankRatio={}|bankCost={}|chargeCost={}", settleLog.getPartnerId(), partnerSettleAmount, bankRatio, bankCost, chargeCost);
        settleLog.setPartnerSettleAmount(partnerSettleAmount);
        //入库
        partnerInsiderSettleLogManager.save(settleLog);
    }

    private boolean hasStated(PartnerInsiderSettleLog settleLog) {
        // 尝试通过时间加id获取数据
        PartnerInsiderSettleLog settleLogRecord = partnerInsiderSettleLogManager.findByMonthOfYear(settleLog.getYear(), settleLog.getMonth(), settleLog.getUserId());
        // 若果查到了数据，表示不需要在插入记录了
        return settleLogRecord != null;
    }
}
